﻿#region USING STATEMENTS

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

using BrickBreaker.Core;
using System;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
using System.ComponentModel;

#endregion

namespace BrickBreaker.Gameplay
{
    public class BBLevelController
    {
        #region DATA_MEMBERS
        //
        #region DEBUG_VARS
        private BBBackground pauseBG;
        private BBBackground grid;
        private BBBackground uncheckedBox;
        private BBBackground checkedBox; 
        #endregion

        //Tracks the global pause state of the current level
        private bool isPaused = false;

        //Tracks whether player has Won/Lost Game
        private bool allLevelsCompleted = false;
        private bool isGameOver = false;
        
        //Used for Debug Checkbox
        private MouseState mouseStateCurrent, mouseStatePrevious;

        //Stores the current existing level being played; 
        private BBLevelStencil currentLevel;

        #region TRACK_LEVEL_PROGRESS

        private int totalLevelCount;
        private int nextClassicLevel = 0; 

        #endregion

        // DO NOT MODIFY
        private string path = Directory.GetCurrentDirectory().Remove(Directory.GetCurrentDirectory().IndexOf("bin")) + @"Content\Levels\"; 
        //
        #endregion DATA_MEMBERS


        #region PROPERTIES
        //
        public bool AreAllLevelsCompleted
        {
            get { return allLevelsCompleted; }
        }

        public bool IsGameOver
        {
            get { return isGameOver; }
        }
        //
        #endregion


        #region OBJECT CONSTRUCTION
        //
        private BBLevelController() { /*Private Constructor*/ }

        //Making sure ONLY 1 copy of 'BBLevelSelector' is created...
        private static BBLevelController controller = null;

        //Static Instance of BBDefaultGame
        public static BBLevelController Instance()
        {
            if (null == controller)
            {
                controller = new BBLevelController();
            }

            return controller;
        }
        //
        #endregion OBJECT CONSTRUCTION


        #region BBILevel_Methods
        //
        public void LoadContent()
        {
            pauseBG = new BBBackground(BBGlobalConfig.background_pause);

            #region DEBUG_LOAD-CONTENT
            //
            grid = new BBBackground(BBGlobalConfig.background_grid);
            uncheckedBox = new BBBackground(BBGlobalConfig.UncheckedBox, new Vector2((BBGlobalConfig.WindowWidth - 32), 32), new Vector2(16.0f, 16.0f));
            checkedBox = new BBBackground(BBGlobalConfig.CheckedBox, new Vector2((BBGlobalConfig.WindowWidth - 32), 32), new Vector2(16.0f, 16.0f));
            //
            #endregion
            totalLevelCount = GetLevelCount(path);
            currentLevel = NextClassicLevel(path);
            currentLevel.LoadContent();

            BBGlobalConfig.hud.BrickCount = currentLevel.BricksLeft;
        }

        public void UnloadContent()
        {
            currentLevel.UnloadContent();
        }

        public void Reset()
        {
            currentLevel.Reset();
            // possible reset Hud: Time variable here
        }

        public void Update(GameTime gameTime)
        {
            mouseStateCurrent = Mouse.GetState();

            #region ESCAPE GAME

            if (BBGlobalConfig.keyboard.Escape)
            {
                BBGlobalConfig.programState = ProgramState.MENU;
                BBGlobalConfig.menuState = MenuState.MAIN;
                //
                Reset();
            }
            #endregion ESCAPE GAME

            #region PAUSE
            if (BBGlobalConfig.keyboard.Pause)
            {
                if (isPaused) { isPaused = false; }
                else { isPaused = true; }

                currentLevel.Paused = isPaused;
            }
            #endregion PAUSE

            #region NOT PAUSED
            if (!isPaused)
            {
                // current level exists
                if (currentLevel != null)
                {
                    // current level still has bricks
                    if (!currentLevel.LevelCompleted)
                    {
                        // Still have lives
                        if (BBGlobalConfig.hud.HasLives)
                        {
                            // update the level
                            currentLevel.Update(gameTime);

                            // make sure its not game over
                            isGameOver = false;
                        }
                        // Game Over
                        else { isGameOver = true; }
                    }
                    // current level has no more bricks
                    else
                    {
                        BBGlobalConfig.SetVolume(1.0f);
                        BBGlobalConfig.LevelWonSound.Play();

                        BBGlobalConfig.powerupManager.UnlockNewPowerUp();

                        currentLevel.UnloadContent();

                        // Assign next level 
                        currentLevel = NextClassicLevel(path);

                        // if level exists
                        if (currentLevel != null)
                        {
                            // make sure new level isn't complete
                            allLevelsCompleted = false;

                            // load new levels content
                            currentLevel.LoadContent();

                            // reset all power ups so none exist
                            BBGlobalConfig.powerupManager.Reset();

                            // Reassign the hud brick count with the number of bricks in new level
                            BBGlobalConfig.hud.BrickCount = currentLevel.BricksLeft;
                        }
                        // if no level exists, all levels are complete
                        else
                        {
                            allLevelsCompleted = true;
                        }
                    }
                }

                BBGlobalConfig.hud.Update(gameTime);
            }
            #endregion

            #region DEBUG_UPDATE
            if (BBGlobalConfig.DisplayDebug == false)
            {
                // if the mouse position is in the sprites position
                if (mouseStateCurrent.X >= uncheckedBox.Position.X &&
                    mouseStateCurrent.X <= uncheckedBox.Position.X + uncheckedBox.Size.X &&
                    mouseStateCurrent.Y >= uncheckedBox.Position.Y &&
                    mouseStateCurrent.Y <= uncheckedBox.Position.Y + uncheckedBox.Size.Y &&
                    mouseStateCurrent.LeftButton == ButtonState.Pressed &&
                    mouseStatePrevious.LeftButton == ButtonState.Released)
                {
                    BBGlobalConfig.DisplayDebug = true;
                }
            }
            else
            {
                // if the mouse position is in the sprites position
                if (mouseStateCurrent.X >= checkedBox.Position.X &&
                    mouseStateCurrent.X <= checkedBox.Position.X + checkedBox.Size.X &&
                    mouseStateCurrent.Y >= checkedBox.Position.Y &&
                    mouseStateCurrent.Y <= checkedBox.Position.Y + checkedBox.Size.Y &&
                    mouseStateCurrent.LeftButton == ButtonState.Pressed &&
                    mouseStatePrevious.LeftButton == ButtonState.Released)
                {
                    BBGlobalConfig.DisplayDebug = false;
                }
            }
            #endregion

            //update the mouse
            mouseStatePrevious = mouseStateCurrent;
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            // only draw the level if it exists
            if (currentLevel != null)
            {
                currentLevel.Draw(spriteBatch);
            }
            
            if (isPaused)
            {
                pauseBG.Draw(spriteBatch);
            }
            
            BBGlobalConfig.hud.Draw(spriteBatch);
            
            #region DEBUG_DISPLAY
            if (BBGlobalConfig.DisplayDebug == true)
            {
                spriteBatch.DrawString(BBGlobalConfig.font, "Toggle Debug Off", new Vector2(checkedBox.Position.X - 130, (checkedBox.Position.Y - 30)), Color.White);
                checkedBox.Draw(spriteBatch);
                grid.Draw(spriteBatch);
            }
            else
            {
                spriteBatch.DrawString(BBGlobalConfig.font, "Toggle Debug On", new Vector2(uncheckedBox.Position.X - 130, (uncheckedBox.Position.Y - 30)), Color.White);
                uncheckedBox.Draw(spriteBatch);
            }
            #endregion DEBUG_DISPLAY
        }
        //
        #endregion BBILevel_Methods

        public int GetLevelCount(string path)
        {
            bool anyLevelsLeft = true;
            int count = 0;
            BBLevelStencil level;

            while (anyLevelsLeft)
            {
                level = GetLevel(path);//NextClassicLevel();

                if (null == level)
                {
                    anyLevelsLeft = false;
                }
                else
                {
                    anyLevelsLeft = true;
                    count++;
                }
            }
               
            return count;
        }

        #region LEVEL_SELECTION_METHODS

        //Get Next Level, based on GameMode Selection
        public bool NextLevel(GameModes gameMode)
        {
            bool anyLevelsLeft = true;
            
            #region GAME-MODE_SELECTION
            switch (gameMode)
            {
                #region Other modes
                //case GameModes.CLASSIC:
                    //if ( null == NextClassicLevel() )
                    //{
                    //    anyLevelsLeft = false;
                    //}
                    //else
                    //{
                    //    anyLevelsLeft = true;
                    //    currentLevel = NextClassicLevel();
                    //}
                //    break;
                //case GameModes.TIMED:
                    //if ( null == NextTimedLevel();() )
                    //{
                    //    anyLevelsLeft = false;
                    //}
                    //else
                    //{
                    //    anyLevelsLeft = true;
                    //    currentLevel = NextTimedLevel();();
                    //}
                //    break;
                //case GameModes.ENDLESS:
                    //if ( null == NextEndlessLevel() )
                    //{
                    //    anyLevelsLeft = false;
                    //}
                    //else
                    //{
                    //    anyLevelsLeft = true;
                    //    currentLevel = NextEndlessLevel();
                    //}
                //    break;
                //case GameModes.PvP:
                    //if ( null == NextPvPLevel() )
                    //{
                    //    anyLevelsLeft = false;
                    //}
                    //else
                    //{
                    //    anyLevelsLeft = true;
                    //    currentLevel = NextPvPLevel();
                    //}
                //    break;
                //case GameModes.PvC:
                    //if ( null == NextPvCLevel() )
                    //{
                    //    anyLevelsLeft = false;
                    //}
                    //else
                    //{
                    //    anyLevelsLeft = true;
                    //    currentLevel = NextPvCLevel();
                    //}
                //  break;
                //case GameModes.MISC:
                    //if ( null == NextMISCLevel() )
                    //{
                    //    anyLevelsLeft = false;
                    //}
                    //else
                    //{
                    //    anyLevelsLeft = true;
                    //    currentLevel = NextMISCLevel();
                    //}
                //  break;
                #endregion
                //***Remove Default once, other game modes are complete...
                default:
                    currentLevel = NextClassicLevel(path);

                    if (null == currentLevel) 
                    { 
                        anyLevelsLeft = false;
                    }
                    else { anyLevelsLeft = true;
                    }
                    break;
            } 
            #endregion

            return anyLevelsLeft;
        }

        private BBLevelStencil NextClassicLevel(string path)
        {
            //string filePath = @"C:\Users\Matthew\Documents\Visual Studio 2008\Projects\AppliedProject\BrickBreaker\Content\Levels\";
            
            ++nextClassicLevel;
            //Reset Level Progress if all Levels are Completed
            if (nextClassicLevel > totalLevelCount)
            {
                nextClassicLevel = 1;
            }

            string ClassicPath = "ClassicLevel_" + nextClassicLevel.ToString() + ".xml";
            //switch (nextClassicLevel)
            //{
                //case 1:
                    //return new BBClassicLevel1();
                    return new BBClassicLevels(path + ClassicPath);//"ClassicLevel_1.xml");
            //    case 2:
            //    //    //return new BBClassicLevel2();
            //        return new BBClassicLevels(path + "ClassicLevel_2.xml");
            //    case 3:
            //        return new BBClassicLevels(path + "ClassicLevel_3.xml");
            //    case 4:
            //        return new BBClassicLevels(path + "ClassicLevel_4.xml");
            //    case 5:
            //        return new BBClassicLevels(path + "ClassicLevel_5.xml");
            //    default:
            //        return null;
            //}
        }

        private BBLevelStencil GetLevel(string path)
        {
            //string filePath = @"C:\Users\Matthew\Documents\Visual Studio 2008\Projects\AppliedProject\BrickBreaker\Content\Levels\";
            ++nextClassicLevel;

            
            switch (nextClassicLevel)
            {
                case 1:
                    //return new BBClassicLevel1();
                    return new BBClassicLevels(path + "ClassicLevel_1.xml");
                case 2:
                    //return new BBClassicLevel2();
                    return new BBClassicLevels(path + "ClassicLevel_2.xml");
                case 3:
                    return new BBClassicLevels(path + "ClassicLevel_3.xml");
                case 4:
                    return new BBClassicLevels(path + "ClassicLevel_4.xml");
                case 5:
                    return new BBClassicLevels(path + "ClassicLevel_5.xml");
                //break;
                default:
                    return null;
                //break;
            }
        }

        public void ResetLevels()
        {
            nextClassicLevel = 0;
            allLevelsCompleted = false;
            isGameOver = false;
            currentLevel = NextClassicLevel(path);
            currentLevel.LoadContent();
            currentLevel.Reset();
            BBGlobalConfig.hud.Lives = 3;
        }
        #endregion


    }//end class
}//end namespace